﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Circle.Domain.Interface.Service;
using Circle.Domain.Entity;
using Circle.Domain.Interface.UnitOfWork;
using Circle.Web.ViewModelsClient;
using Circle.Web.ViewModels;
using System.Web.Mvc;
using Circle.Manager;
using Circle.Domain.Model;
using Circle.Web.Drivers.Contract;

namespace Circle.Web.Drivers
{
    public abstract class SavableDriver<VM, CM> : ConvertableDriver<VM, CM>, ISavableDriver<VM, CM>
        where VM : ViewModel, new()
        where CM : ClientModel, new()
    {

        #region Savable

        public virtual OperationStatus Save(CM cModel, string[] includeProperties = null, string[] excludeProperties = null)
        {
            try
            {
                if (cModel == null) return OperationStatus.DataFormatError;
                VM vModel = Create(includeProperties);
                vModel = FromClient(vModel, cModel);
                OperationStatus status = Save(vModel);
                if (status == OperationStatus.Success)
                {
                    ToClient(vModel, cModel, excludeProperties);
                }
                else
                {
                    cModel.ServerStatus = false;
                }
                return status;
            }
            catch
            {
                cModel.ServerStatus = false;
                return OperationStatus.GenericError;
            }
        }

        public abstract OperationStatus Save(VM vModel);

        #endregion

    }


    public abstract class SavableEntityDriver<E, CM> : ConvertableEntityDriver<E, CM>, ISavableDriver<E, CM>
        where E : BaseEntity
        where CM : IdenticalClientModel, new()
    {
        public SavableEntityDriver(IBaseCrudService<E> service):base(service)
        { }

        #region Savable

        public virtual OperationStatus Save(CM cModel, string[] includeProperties = null, string[] excludeProperties = null)
        {
            try
            {
                if (cModel == null) return OperationStatus.DataFormatError;
                E entity = null;
                if (cModel.isNew())
                {
                    entity = Create(includeProperties);
                }
                else
                {
                    entity = Get(cModel.Id, includeProperties);
                }
                entity = FromClient(entity, cModel, includeProperties);
                OperationStatus status = Save(entity);
                if (status == OperationStatus.Success)
                {
                    ToClient(entity, cModel, excludeProperties);
                }
                else
                {
                    cModel.ServerStatus = false;
                }
                return status;
            }
            catch
            {
                cModel.ServerStatus = false;
                return OperationStatus.GenericError;
            }
        }

        public virtual OperationStatus Save(E entity)
        {
            return CrudService.Save(entity);
        }

        #endregion
    }

}